﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.XPath;

namespace Engine.Sgml.XPath {
    static class SgmlNavigatorExtension {
        /// <summary>
        /// Selects an element using a XPath expression.
        /// </summary>
        /// <param name="navigator"></param>
        /// <param name="expression">A string that contains a XPath expression.</param>
        /// <returns></returns>
        public static SElement SelectElement(this SgmlNavigator navigator, string expression) {
            Guard.ArgumentNotNull(expression, "expression");
            SgmlNavigator result = (SgmlNavigator)navigator.SelectSingleNode(expression);
            if (result == null)
                return null;
            else
                return result.UnderlyingElement;
            }

        /// <summary>
        /// Selects an attribute using a XPath expression.
        /// </summary>
        /// <param name="navigator"></param>
        /// <param name="expression">A string that contains a XPath expression.</param>
        /// <returns></returns>
        public static SAttribute SelectAttribute(this SgmlNavigator navigator, string expression) {
            Guard.ArgumentNotNull(expression, "expression");
            SgmlNavigator result = (SgmlNavigator)navigator.SelectSingleNode(expression);
            if (result == null)
                return null;
            else
                return result.UnderlyingAttribute;
            }

        /// <summary>
        /// Selects a collection of elements using a XPath expression.
        /// </summary>
        /// <param name="navigator"></param>
        /// <param name="expression">A string that contains a XPath expression.</param>
        /// <returns></returns>
        public static IEnumerable<SElement> SelectElements(this SgmlNavigator navigator, string expression) {
            Guard.ArgumentNotNull(expression, "expression");
            XPathNodeIterator iterator = navigator.Select(expression);
            SElement[] elements = new SElement[iterator.Count];
            while (iterator.MoveNext()) {
                elements[iterator.CurrentPosition - 1] = ((SgmlNavigator)iterator.Current).UnderlyingElement;
                }
            return elements;
            }

        /// <summary>
        /// Selects a collection of attributes using a XPath expression.
        /// </summary>
        /// <param name="navigator"></param>
        /// <param name="expression">A string that contains a XPath expression.</param>
        /// <returns></returns>
        public static IEnumerable<SAttribute> SelectAttributes(this SgmlNavigator navigator, string expression) {
            Guard.ArgumentNotNull(expression, "expression");
            XPathNodeIterator iterator = navigator.Select(expression);
            SAttribute[] elements = new SAttribute[iterator.Count];
            while (iterator.MoveNext()) {
                elements[iterator.CurrentPosition - 1] = ((SgmlNavigator)iterator.Current).UnderlyingAttribute;
                }
            return elements;
            }
        }
    }
